#include "wifi_drv.h"
#include "delay.h"

static volatile uint8_t recvDataBuf[WIFI_MAX_BUF_SIZE];
static uint32_t recvDataLen = 0;

/**
 * @desc  : 引脚配置
 * @date  : 2025-08-11
 * @author: AnRui
 * @note  :
 */
static void WIFIDrvGpioConfig(void) {
    rcu_periph_clock_enable(WIFI_UART_ENABLE_RCU);
    gpio_init(WIFI_UART_ENABLE_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_2MHZ, WIFI_UART_ENABLE_PIN);

    rcu_periph_clock_enable(WIFI_UART_TX_RCU);
    gpio_init(WIFI_UART_TX_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, WIFI_UART_TX_PIN);

    rcu_periph_clock_enable(WIFI_UART_RX_RCU);
    gpio_init(WIFI_UART_RX_PORT, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, WIFI_UART_RX_PIN);
}

/**
 * @desc  : UART配置
 * @date  : 2025-08-11
 * @author: AnRui
 * @note  :  8位数据位 1位停止位 0位校验位
 *           使能空闲中断 结合dma保存接收到的数据
 */
static void WIFIUartConfig(void) {
    /* 使能UART时钟；*/
    rcu_periph_clock_enable(WIFI_UART_RCU);
    /* 复位UART；*/
    usart_deinit(WIFI_UART_NO);
    /* 通过USART_CTL0寄存器的WL设置字长；*/
    usart_word_length_set(WIFI_UART_NO, USART_WL_8BIT);
    /* 通过USART_CTL0寄存器的PCEN设置校验位；*/
    usart_parity_config(WIFI_UART_NO, USART_PM_NONE);
    /* 在USART_CTL1寄存器中写STB[1:0]位来设置停止位的长度；*/
    usart_stop_bit_set(WIFI_UART_NO, USART_STB_1BIT);
    /* 在USART_BAUD寄存器中设置波特率；*/
    usart_baudrate_set(WIFI_UART_NO, WIFI_UART_BAURATE);
    /* 在USART_CTL0寄存器中设置TEN位，使能发送功能；*/
    usart_transmit_config(WIFI_UART_NO, USART_TRANSMIT_ENABLE);
    /* 在USART_CTL0寄存器中设置TEN位，使能接收功能；*/
    usart_receive_config(WIFI_UART_NO, USART_RECEIVE_ENABLE);
    /* 使能串口接收空闲中断；*/
    usart_interrupt_enable(WIFI_UART_NO, USART_INT_IDLE);
    /* 使能串口中断；*/
    nvic_irq_enable(WIFI_UART_IRQ, WIFI_UART_IRQ_PRIORITY);
    /* 在USART_CTL0寄存器中置位UEN位，使能UART；*/
    usart_enable(WIFI_UART_NO);
    /* 使能UART接收数据使用DMA；*/
    usart_dma_receive_config(WIFI_UART_NO, USART_RECEIVE_DMA_ENABLE);
}

/**
 * @desc  : DMA配置
 * @date  : 2025-08-11
 * @author: AnRui
 * @note  : 外设到内存
 *
 */
static void WIFIDmaConfig(void) {
    /* 使能DMA时钟；*/
    rcu_periph_clock_enable(WIFI_DMA_RCU);
    /* 复位DMA通道；*/
    dma_deinit(WIFI_DMA_NO, WIFI_DMA_CH);
    dma_parameter_struct dmaStruct;
    /* 配置传输方向；外设-*/
    dmaStruct.direction = DMA_PERIPHERAL_TO_MEMORY;
    /* 配置数据源地址；(uint32_t)(&USART_DATA(WIFI_UART_NO)*/
    dmaStruct.periph_addr = (USART2 + 0x04);
    /* 配置源地址是固定的还是增长的；*/
    dmaStruct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
    /* 配置源数据传输位宽；*/
    dmaStruct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
    /* 配置数据目的地址；*/
    dmaStruct.memory_addr = (uint32_t)recvDataBuf;
    /* 配置目的地址是固定的还是增长的；*/
    dmaStruct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
    /* 配置目的数据传输位宽；*/
    dmaStruct.memory_width = DMA_MEMORY_WIDTH_8BIT;
    /* 配置数据传输最大次数；*/
    dmaStruct.number = WIFI_MAX_BUF_SIZE;
    /* 配置DMA通道优先级；*/
    dmaStruct.priority = DMA_PRIORITY_HIGH;
    dma_init(WIFI_DMA_NO, WIFI_DMA_CH, &dmaStruct);
    /* 使能DMA通道；*/
    dma_channel_enable(WIFI_DMA_NO, WIFI_DMA_CH);
}

/**
 * @desc  : wifi模块硬件复位
 * @date  : 2025-08-11
 * @author: AnRui
 * @note  :
 */
void WIFIHardReset(void) {
    printf("wifi module,now hwreset it!\n");
    gpio_bit_reset(WIFI_UART_ENABLE_PORT, WIFI_UART_ENABLE_PIN);
    DelayNms(100);
    gpio_bit_set(WIFI_UART_ENABLE_PORT, WIFI_UART_ENABLE_PIN);
    DelayNms(100);
}

/**
 * @desc  : 清理整个缓冲区
 * @date  : 2025-08-15
 * @author: AnRui
 * @note  :
 */
void  WIFIClearRecvDataBuf() {
    memset((void*)recvDataBuf, 0, WIFI_MAX_BUF_SIZE);
}

/**
 * @desc  : uart空闲中断
 * @date  : 2025-08-11
 * @author: AnRui
 * @note  : 注意: 1.清除uart的空闲标志位 分为两步才可以清除干净
 *               2.重新配置DMA计数器 传输一个字节 就会-1
 *               3.\0 对应的ASCII就是0
 *
 */
void USART2_IRQHandler(void) {
    if (usart_interrupt_flag_get(WIFI_UART_NO, USART_INT_FLAG_IDLE) != RESET) {
        usart_interrupt_flag_clear(WIFI_UART_NO, USART_INT_FLAG_IDLE);  //第一步，读取stat0寄存器，清除IDLE标志位
        usart_data_receive(WIFI_UART_NO);                               //第二步，读取数据寄存器，清除IDLE标志位
        recvDataLen = WIFI_MAX_BUF_SIZE - dma_transfer_number_get(WIFI_DMA_NO, WIFI_DMA_CH);
        if (recvDataLen) {
            recvDataBuf[recvDataLen] = '\0';
            printf("uart recv str:%s\n", recvDataBuf);
        }
        dma_channel_disable(WIFI_DMA_NO, WIFI_DMA_CH);
        // 重新配置DMA计数器
        dma_transfer_number_config(WIFI_DMA_NO, WIFI_DMA_CH, WIFI_MAX_BUF_SIZE);
        dma_channel_enable(WIFI_DMA_NO, WIFI_DMA_CH);
    }
}


/**
 * @desc  : 获取从WIFI模块返回的数据
 * @date  : 2025-08-11
 * @author: AnRui
 * @return: char*
 * @note  :
 */
char* GetDataFromWIFI(void) {
    return (char*)recvDataBuf;
}

/**
 * @desc  : 向WIFI模块发送数据
 * @date  : 2025-08-11
 * @author: AnRui
 * @param : data - {参数说明}:
 * @note  :
 */
void SendDataToWIFI(char* data) {
    printf("uart send str:%s\n", data);
    while (*data != '\0') {
        usart_data_transmit(WIFI_UART_NO, *data);
        while (RESET == usart_flag_get(WIFI_UART_NO, USART_FLAG_TBE));
        data++;
    }
}


/**
 * @desc  : WIFI驱动初始化
 * @date  : 2025-08-11
 * @author: AnRui
 * @note  :
 */
void WIFIDrvInit(void) {
    WIFIDrvGpioConfig();
    WIFIUartConfig();
    WIFIDmaConfig();
    WIFIHardReset();
}



